package org.lanyu.springainovel.novel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.lanyu.springainovel.chat.service.PromptTemplateService;
import org.lanyu.springainovel.common.config.ChatModelManager;
import org.lanyu.springainovel.common.entity.MyPromptTemplate;
import org.lanyu.springainovel.common.service.UserService;
import org.lanyu.springainovel.common.service.WebSocketService;
import org.lanyu.springainovel.common.utils.TaskIdGenerator;
import org.lanyu.springainovel.novel.entity.BookAnalysisRecord;
import org.lanyu.springainovel.novel.entity.BookAnalysisResult;
import org.lanyu.springainovel.novel.mapper.BookAnalysisRecordMapper;
import org.lanyu.springainovel.novel.mapper.BookAnalysisResultMapper;
import org.lanyu.springainovel.novel.service.BookAnalysisRecordService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 拆书服务实现类
 */
@Service
public class BookAnalysisRecordServiceImpl implements BookAnalysisRecordService {

    @Autowired
    private BookAnalysisRecordMapper bookAnalysisRecordMapper;

    @Autowired
    private BookAnalysisResultMapper bookAnalysisResultMapper;

    @Autowired
    private PromptTemplateService promptTemplateService;

    @Autowired
    private UserService userService;
    
    @Autowired
    private WebSocketService webSocketService;

    @Autowired
    private ChatModelManager chatModelManager;

    @Value("${ai.file.upload-dir}")
    private String uploadDir;

    // 存储运行中的任务ID
    private final Map<Long, String> runningTasks = new ConcurrentHashMap<>();

    @Transactional
    @Override
    public BookAnalysisRecord createRecordAndStartAnalysis(BookAnalysisRecord record) {
        // 设置创建时间和更新时间
        record.setCreateTime(new Date());
        record.setUpdateTime(new Date());
        
        // 如果状态未设置，默认为PENDING
        if (record.getStatus() == null) {
            record.setStatus("PENDING");
        }
        
        // 如果进度未设置，默认为0
        if (record.getProgress() == null) {
            record.setProgress(0);
        }

        // 保存记录
        bookAnalysisRecordMapper.insert(record);

        // 异步开始分析
        startAnalysisAsync(record.getId());

        return record;
    }

    @Transactional
    @Override
    public BookAnalysisRecord createRecordAndStartAnalysis(String name, String sourceType, String sourcePath,
                                                           String sourceUrl, Long systemPromptId, Long modelId,
                                                           String userPrompt, Long userId) {
        // 创建记录
        BookAnalysisRecord record = new BookAnalysisRecord();
        record.setName(name);
        record.setUserId(userId);
        record.setStatus("PENDING");
        record.setProgress(0);
        record.setSourceType(sourceType);
        record.setSourcePath(sourcePath);
        record.setSourceUrl(sourceUrl);
        record.setSystemPromptId(systemPromptId);
        record.setModelId(modelId);
        record.setUserPrompt(userPrompt);
        record.setCreateTime(new Date());
        record.setUpdateTime(new Date());

        // 保存记录
        bookAnalysisRecordMapper.insert(record);

        // 异步开始分析
        startAnalysisAsync(record.getId());

        return record;
    }

    @Override
    public List<BookAnalysisRecord> getUserRecords() {
        // 获取当前用户ID
        Long userId = userService.getCurrentUser().getId();
        
        LambdaQueryWrapper<BookAnalysisRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BookAnalysisRecord::getUserId, userId);
        queryWrapper.orderByDesc(BookAnalysisRecord::getCreateTime);
        return bookAnalysisRecordMapper.selectList(queryWrapper);
    }

    @Override
    public Page<BookAnalysisRecord> getUserRecords(Long userId, int page, int size) {
        Page<BookAnalysisRecord> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<BookAnalysisRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BookAnalysisRecord::getUserId, userId);
        queryWrapper.orderByDesc(BookAnalysisRecord::getCreateTime);
        return bookAnalysisRecordMapper.selectPage(pageParam, queryWrapper);
    }

    @Override
    public BookAnalysisRecord getRecordById(Long id) {
        return bookAnalysisRecordMapper.selectById(id);
    }

    @Override
    public BookAnalysisRecord updateRecord(BookAnalysisRecord record) {
        // 设置更新时间
        record.setUpdateTime(new Date());
        
        // 更新记录
        bookAnalysisRecordMapper.updateById(record);
        return record;
    }

    @Transactional
    @Override
    public BookAnalysisRecord updateRecord(Long id, String name, Long systemPromptId, Long modelId, String userPrompt) {
        BookAnalysisRecord record = bookAnalysisRecordMapper.selectById(id);
        if (record == null) {
            throw new RuntimeException("记录不存在");
        }

        record.setName(name);
        record.setSystemPromptId(systemPromptId);
        record.setModelId(modelId);
        record.setUserPrompt(userPrompt);
        record.setUpdateTime(new Date());

        bookAnalysisRecordMapper.updateById(record);
        return record;
    }

    @Override
    @Transactional
    public boolean deleteRecord(Long id) {
        // 检查任务是否正在运行
        if (runningTasks.containsKey(id)) {
            throw new RuntimeException("任务正在运行中，无法删除");
        }

        // 删除相关的结果
        LambdaQueryWrapper<BookAnalysisResult> resultQueryWrapper = new LambdaQueryWrapper<>();
        resultQueryWrapper.eq(BookAnalysisResult::getRecordId, id);
        bookAnalysisResultMapper.delete(resultQueryWrapper);

        // 删除记录
        return bookAnalysisRecordMapper.deleteById(id) > 0;
    }

    @Override
    public String saveUploadedFile(MultipartFile file) {
        try {
            // 创建上传目录
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String extension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String fileName = UUID.randomUUID().toString() + extension;
            Path filePath = uploadPath.resolve(fileName);

            // 保存文件
            Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);

            return filePath.toString();
        } catch (IOException e) {
            throw new RuntimeException("保存文件失败: " + e.getMessage());
        }
    }
    
    @Override
    public Set<Long> getRunningTaskIds() {
        return new HashSet<>(runningTasks.keySet());
    }
    
    @Override
    public CompletableFuture<Void> executeAnalysisAsync(BookAnalysisRecord record) {
        return CompletableFuture.runAsync(() -> startAnalysisAsync(record.getId()));
    }
    
    @Override
    public CompletableFuture<Void> processFileAndStartAnalysis(BookAnalysisRecord record, MultipartFile file) {
        return CompletableFuture.runAsync(() -> {
            try {
                // 保存文件
                String filePath = saveUploadedFile(file);
                record.setSourceType("FILE");
                record.setSourcePath(filePath);
                
                // 创建记录并开始分析
                createRecordAndStartAnalysis(record);
            } catch (Exception e) {
                throw new RuntimeException("处理文件并启动分析失败: " + e.getMessage(), e);
            }
        });
    }

    @Override
    @Transactional
    public BookAnalysisRecord restartAnalysis(Long id) {
        BookAnalysisRecord record = bookAnalysisRecordMapper.selectById(id);
        if (record == null) {
            throw new RuntimeException("记录不存在");
        }

        // 检查任务是否正在运行
        if (runningTasks.containsKey(id)) {
            throw new RuntimeException("任务正在运行中，无法重新开始");
        }

        // 删除之前的结果
        LambdaQueryWrapper<BookAnalysisResult> resultQueryWrapper = new LambdaQueryWrapper<>();
        resultQueryWrapper.eq(BookAnalysisResult::getRecordId, id);
        bookAnalysisResultMapper.delete(resultQueryWrapper);

        // 重置状态
        record.setStatus("PENDING");
        record.setProgress(0);
        record.setStartTime(null);
        record.setEndTime(null);
        record.setErrorMessage(null);
        record.setUpdateTime(new Date());

        bookAnalysisRecordMapper.updateById(record);

        // 异步开始分析
        startAnalysisAsync(record.getId());

        return record;
    }

    @Override
    public BookAnalysisRecord getRecordStatus(Long id) {
        BookAnalysisRecord record = bookAnalysisRecordMapper.selectById(id);
        return record;
    }

    @Override
    public List<BookAnalysisResult> getRecordResults(Long id) {
        LambdaQueryWrapper<BookAnalysisResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BookAnalysisResult::getRecordId, id);
        queryWrapper.orderByAsc(BookAnalysisResult::getChapterIndex);
        return bookAnalysisResultMapper.selectList(queryWrapper);
    }

    /**
     * 异步开始分析
     *
     * @param recordId 记录ID
     */
    @Async
    public void startAnalysisAsync(Long recordId) {
        runningTasks.put(recordId, Thread.currentThread().getName());
        try {
            // 获取记录
            BookAnalysisRecord record = bookAnalysisRecordMapper.selectById(recordId);
            if (record == null) {
                return;
            }

            // 生成规范的任务ID
            String taskId = TaskIdGenerator.generateAnalysisTaskId(recordId);

            // 更新状态为处理中
            record.setStatus("PROCESSING");
            record.setStartTime(new Date());
            record.setUpdateTime(new Date());
            bookAnalysisRecordMapper.updateById(record);

            // 通知WebSocket
            webSocketService.sendRecordProgress(recordId, 0, "开始分析...");

            // 获取书籍内容
            String bookContent = getBookContent(record);
            if (bookContent == null || bookContent.isEmpty()) {
                throw new RuntimeException("无法获取书籍内容");
            }

            // 获取系统提示词
            String systemPrompt = getSystemPrompt(record.getSystemPromptId());
            if (systemPrompt == null) {
                systemPrompt = "你是一个专业的书籍分析师，请对提供的书籍内容进行分析，生成章节概要和详细拆解";
            }

            // 获取AI模型
            ChatModel chatModel = chatModelManager.getOrCreateChatModelById(record.getModelId());
            if (chatModel == null) {
                throw new RuntimeException("无法获取AI模型");
            }

            // 创建ChatClient
            ChatClient chatClient = ChatClient.builder(chatModel)
                    .build();

            // 更新进度
            record.setProgress(10);
            record.setUpdateTime(new Date());
            bookAnalysisRecordMapper.updateById(record);
            webSocketService.sendRecordProgress(recordId, 10, "正在生成书籍概要...");

            // 生成书籍概要
            String overviewPrompt = systemPrompt + "\n\n请为以下书籍内容生成一个概要（不超过100字）：\n\n" + bookContent;
            Prompt overviewPromptObj = new Prompt(overviewPrompt);
            String overview = chatClient.prompt(overviewPromptObj).call().content();

            // 保存概要结果
            BookAnalysisResult overviewResult = new BookAnalysisResult();
            overviewResult.setRecordId(recordId);
            overviewResult.setResultType("OVERVIEW");
            overviewResult.setTitle("书籍概要");
            overviewResult.setContent(overview);
            overviewResult.setCreateTime(new Date());
            bookAnalysisResultMapper.insert(overviewResult);

            // 更新进度
            record.setProgress(30);
            record.setUpdateTime(new Date());
            bookAnalysisRecordMapper.updateById(record);
            webSocketService.sendRecordProgress(recordId, 30, "正在生成章节拆解...");

            // 生成章节拆解
            String chapterPrompt = systemPrompt + "\n\n请将以下书籍内容拆分为章节（每个章节包含标题和详细内容）：\n\n" + bookContent;
            Prompt chapterPromptObj = new Prompt(chapterPrompt);
            String chapterResult = chatClient.prompt(chapterPromptObj).call().content();

            // 解析章节结果并保存
            List<BookAnalysisResult> chapterResults = parseChapterResults(recordId, chapterResult);
            for (BookAnalysisResult chapter : chapterResults) {
                bookAnalysisResultMapper.insert(chapter);
            }

            // 更新进度为完成
            record.setProgress(100);
            record.setStatus("COMPLETED");
            record.setEndTime(new Date());
            record.setUpdateTime(new Date());
            bookAnalysisRecordMapper.updateById(record);
            webSocketService.sendRecordProgress(recordId, 100, "分析完成");

        } catch (Exception e) {
            // 更新状态为失败
            BookAnalysisRecord record = bookAnalysisRecordMapper.selectById(recordId);
            if (record != null) {
                record.setStatus("FAILED");
                record.setErrorMessage(e.getMessage());
                record.setEndTime(new Date());
                record.setUpdateTime(new Date());
                bookAnalysisRecordMapper.updateById(record);
                webSocketService.sendRecordProgress(recordId, -1, "分析失败: " + e.getMessage());
            }
        } finally {
            runningTasks.remove(recordId);
        }
    }

    /**
     * 获取书籍内容
     *
     * @param record 记录
     * @return 书籍内容
     */
    private String getBookContent(BookAnalysisRecord record) {
        if ("FILE".equals(record.getSourceType())) {
            return readFileContent(record.getSourcePath());
        } else if ("URL".equals(record.getSourceType())) {
            return fetchUrlContent(record.getSourceUrl());
        }
        return null;
    }

    /**
     * 从URL获取内容
     *
     * @param url URL
     * @return 内容
     */
    private String fetchUrlContent(String url) {
        // 这里应该实现从URL获取内容的逻辑
        // 可以使用HttpClient或其他HTTP客户端库
        try {
            // 简化实现，实际项目中需要更完善的实现
            return "从URL获取的内容 " + url;
        } catch (Exception e) {
            throw new RuntimeException("从URL获取内容失败: " + e.getMessage());
        }
    }

    /**
     * 读取文件内容
     *
     * @param filePath 文件路径
     * @return 文件内容
     */
    private String readFileContent(String filePath) {
        try {
            Path path = Paths.get(filePath);
            if (!Files.exists(path)) {
                throw new RuntimeException("文件不存在 " + filePath);
            }
            return new String(Files.readAllBytes(path), "UTF-8");
        } catch (IOException e) {
            throw new RuntimeException("读取文件失败: " + e.getMessage());
        }
    }

    /**
     * 获取系统提示词
     *
     * @param promptId 提示词ID
     * @return 系统提示词
     */
    private String getSystemPrompt(Long promptId) {
        if (promptId == null) {
            return null;
        }
        MyPromptTemplate promptTemplate = promptTemplateService.getTemplateById(promptId);
        return promptTemplate != null ? promptTemplate.getContent() : null;
    }

    /**
     * 解析章节结果
     *
     * @param recordId 记录ID
     * @param chapterResult 章节结果字符串
     * @return 章节结果列表
     */
    private List<BookAnalysisResult> parseChapterResults(Long recordId, String chapterResult) {
        List<BookAnalysisResult> results = new ArrayList<>();
        
        // 简化实现，实际项目中需要更完善的解析逻辑
        // 这里假设章节结果是以特定格式分隔的
        String[] chapters = chapterResult.split("\n\n");
        
        for (int i = 0; i < chapters.length; i++) {
            String chapter = chapters[i].trim();
            if (chapter.isEmpty()) {
                continue;
            }
            
            BookAnalysisResult result = new BookAnalysisResult();
            result.setRecordId(recordId);
            result.setResultType("CHAPTER");
            result.setChapterIndex(i + 1);
            
            // 尝试提取标题（假设第一行是标题）
            String[] lines = chapter.split("\n");
            if (lines.length > 0) {
                result.setTitle(lines[0].trim());
                
                // 剩余行作为内容
                if (lines.length > 1) {
                    String content = Arrays.stream(lines, 1, lines.length)
                            .collect(Collectors.joining("\n"));
                    result.setContent(content.trim());
                } else {
                    result.setContent(chapter);
                }
            } else {
                result.setTitle("第" + (i + 1) + "章");
                result.setContent(chapter);
            }
            
            result.setCreateTime(new Date());
            results.add(result);
        }
        
        return results;
    }
}